
//给定一个有 N 个点，M 条边的有向无权图，现求其拓扑排序。若有多个拓扑排序，则尽可能让小数在前大数在后
//
//如何求解一个图形的拓扑排序
//第一步：统计每个节点的入度
//第二步：将入度为0的节点压入队列中，然后依次处理队列中的每个点，
//第三步：处理当前节点的时候，将当前节点所指向的其他节点入度减1，如果有节点入度变为0，就将该节点压入到队列的末尾。直到队列为空
//此时队列的出队顺序就是我们要求的拓扑排序


#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;

#define N 2005
int indeg[N];
vector<vector<int>> g(N);
int ans[N], cnt = 0;

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int a, b;
		cin >> a >> b;
		indeg[b] += 1; //记录入度
		g[a].push_back(b); //二维数组
	}
	set<int> q;
	for (int i = 1; i <= n; i++) {
		if (indeg[i] == 0) q.insert(i);
	}
	while (q.size() > 0) {
		int now = *q.begin(); //堆的top()
		ans[cnt++] = now;
		q.erase(q.begin());  //堆的pop() 
		// ————
		for (int i = 0, I = g[now].size(); i < I; i++)
		{
			int t = g[now][i];
			indeg[t] -= 1;
			if (indeg[t] == 0) q.insert(t);
		}
		//————
	}
	for (int i = 0; i < cnt; i++)
	{
		if (i) cout << " ";
		cout << ans[i];
	}

	cout << endl;
	return 0;
}